home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / bardcol2.zip / BARDCOL1.EXE / RSCROLL.ASM < prev   
Assembly Source File  |  1987-04-18  |  8KB  |  165 lines

  1. ;********** RScroll.Asm - horizontal scrolling routine: RIGHT
  2.  
  3. ;Copyright (c) 1987 by Ethan Winer
  4.  
  5. ;Syntax - Call RScroll(UL.Row%, UL.Col%, LR.Row%, LR.Col%, Columns%)
  6. ;                       1-25     1-80     1-25     1-80      1-79
  7.  
  8.  
  9. Code       Segment Byte
  10.            Assume  CS:Code
  11.  
  12. RScroll    Proc Far
  13.  
  14. Begin:     Push BP                  ;save BP and DS for Turbo Basic
  15.            Push DS
  16.            Mov  BP,SP
  17.  
  18.  
  19. ;Get passed parameters and calculate the number of rows, columns, and window width
  20.  
  21.            Mov  SI,[BP+24]          ;put address of UL.Row% into SI
  22.            Mov  DS,[BP+26]          ;put segment of UL.Row into DS
  23.            Mov  AL,[SI]             ;put UL.Row% into AL
  24.            Dec  AL                  ;adjust 1-25 to 0-24 for calculations below
  25.  
  26.            Mov  CL,160              ;prepare to multiply AL by 160
  27.            Mul  CL                  ;now AX holds beginning address of upper row in screen memory
  28.  
  29.            Mov  SI,[BP+12]          ;put address of LR.Col% into SI
  30.            Mov  DS,[BP+14]          ;ditto for segment
  31.            Mov  BX,[SI]             ;put LR.Col% into BX
  32.            Dec  BX                  ;adjust for addition below
  33.            Add  AX,BX               ;add column offset to AX to determine actual start address of screen portion to be scrolled
  34.            Add  AX,BX               ;once more to include the attribute bytes
  35.  
  36.            Mov  BX,AX               ;now BX, which will hold the destination address, is the same as the source address
  37.            Mov  SI,[BP+08]          ;put address of Columns% into SI
  38.            Mov  DS,[BP+10]
  39.            Add  BX,[SI]             ;add to BX to get destination address of memory moves
  40.            Add  BX,[SI]             ;once more to include the attribute bytes
  41.  
  42.  
  43. ;Determine the type of monitor by looking at the equipment list at 0000:0410h
  44.  
  45.            Mov  CX,0                ;set ES to 0 through CX to look at the equipment list in low memory
  46.            Mov  ES,CX
  47.            Mov  CX,0B000h           ;set CX to hold mono screen segment initially, we'll add 800h later if color
  48.            Mov  DL,ES:[410h]        ;get equipment list byte - bit coded to indicate monitor type etc.
  49.            And  DL,30h              ;keep only the bits we care about
  50.            Cmp  DL,30h              ;is it mono?
  51.            JZ   Mono_EGA            ;yes, skip over adding 800h to CX (which will end up in the segment registers DS and ES)
  52.            Add  CX,800h             ;adjust CX to segment of color screen
  53.  
  54.            Mov  DL,ES:[487h]        ;if an EGA is installed, this byte will not be zero
  55.            Cmp  DL,0                ;is it an EGA?
  56.            JNZ  Mono_EGA            ;yes, skip over
  57.            Mov  DX,3DAh             ;no, specify the port to check for retrace
  58.            Jmp  Continue            ;and skip over
  59.  
  60. Mono_EGA:  Mov  DX,0                ;indicate that we don't need to wait for a retrace later
  61.  
  62.  
  63. ;Continue getting the passed parameters
  64.  
  65. Continue:  Mov  ES,CX               ;now ES holds the correct segment for the type of screen in use
  66.            Mov  SI,[BP+16]          ;put address of LR.Row% into SI
  67.            Mov  DS,[BP+18]
  68.            Mov  CH,[SI]             ;put LR.Row% into CH
  69.            Mov  SI,[BP+24]          ;get address for UL.Row%
  70.            Mov  DS,[BP+26]
  71.            Sub  CH,[SI]             ;subtract it from CH to get the number of rows to be processed
  72.            Inc  CH                  ;add 1 because Number_Of_Rows = (LR.Row% - UL.Row%) + 1
  73.  
  74.            Mov  SI,[BP+12]          ;put address of LR.Col% into SI
  75.            Mov  DS,[BP+14]
  76.            Mov  CL,[SI]             ;put LR.Col% into CL
  77.            Mov  SI,[BP+20]          ;get address for UL.Col%
  78.            Mov  DS,[BP+22]
  79.            Sub  CL,[SI]             ;subtract it from CL to get the number of columns to scroll for each row processed
  80.            Inc  CL                  ;add 1 because Number_Of_Columns = (LR.Col% - UL.Col%) + 1
  81.  
  82.  
  83. ;Scroll the screen
  84.  
  85.            Push ES                  ;make both the source and destination segments the same through the stack
  86.            Pop  DS                  ;since the instruction MOV DS,ES is not allowed
  87.            Std                      ;setar direction flag so all memory moves below will be in the backward direction
  88.  
  89. Next_Row:  Mov  SI,AX               ;put the starting source address for moves into SI
  90.            Mov  DI,BX               ;ditto for the starting destination address
  91.            Push AX                  ;save AX because it will get clobbered below
  92.  
  93. Next_Col:  Cmp  DL,0                ;are we doing a mono or EGA screen?
  94.            JZ   Mono                ;yes, skip over waiting for the CGA retrace signal
  95.  
  96. NRetrace:  In   AL,DX               ;wait until not doing a retrace
  97.            Test AL,1
  98.            JNZ  NRetrace
  99. Retrace:   In   AL,DX               ;get the video status byte
  100.            Test AL,1                ;check just the retrace bit - are we doing a retrace now?
  101.            JZ   Retrace             ;no, wait until we are
  102.  
  103. Mono:      Lodsw                    ;get the source character and atrribute
  104.            Stosw                    ;and put it in its new home
  105.            Dec  CL                  ;show that we just did a column
  106.            Jnz  Next_Col            ;continue until CL is zero (done with this row)
  107.  
  108.  
  109. ;Calculate the number of trailing columns to blank out
  110.  
  111.            Pop  AX                  ;retrieve starting address from before
  112.            Push AX                  ;save again for later
  113.            Push BX                  ;save BX for a moment
  114.            Sub  BX,AX               ;the difference between the original source and destination addresses tells how many columns
  115.            Shr  BL,1                ;actually, the difference is twice the number of columns, so divide by two
  116.            Mov  CL,BL               ;and put the count from BL into CL
  117.            Pop  BX                  ;retrieve original destination address
  118.  
  119.  
  120. ;Re-calculate the window width - can't get at the original variables anymore because DS now holds the screen segment
  121.  
  122.            Pop  AX                  ;retrieve starting address again
  123.            Push AX                  ;save again
  124.            Sub  AX,SI               ;the difference between SI and AX (where SI was before) tells how many columns were moved
  125.            Shr  AL,1                ;again, the difference is twice the width because of the attribute bytes, divide by two
  126.            Mov  AH,AL               ;save it in AH because AL gets changed below
  127.  
  128.  
  129. ;Fill remaining columns with blanks
  130.  
  131. Next_Spc:  Cmp  DL,0                ;are we doing mono or EGA?
  132.            JZ   Mono2               ;yes, skip over waiting for retrace
  133.  
  134. NRetrace2: In   AL,DX               ;wait until not doing a retrace
  135.            Test AL,1
  136.            JNZ  NRetrace2
  137. Retrace2:  In   AL,DX               ;get video status byte
  138.            Test AL,1                ;are we doing a retrace now?
  139.            JZ   Retrace2            ;no, wait until we are
  140.  
  141. Mono2:     Mov  AL,32               ;put a blank space into AL to clear rightmost columns after scrolling
  142.            Stosb                    ;put it onto the screen
  143.            Dec  DI                  ;skip over the attribute byte to leave the current color undisturbed
  144.            Dec  CL                  ;decrement the counter that tracks how many blanks we've done so far
  145.            Jnz  Next_Spc            ;until done
  146.            Mov  CL,AH               ;retrieve the number of columns to scroll calculated earlier
  147.  
  148.  
  149. ;Calculate the addresses for the next row
  150.  
  151.            Pop  AX                  ;retrieve AX
  152.            Add  AX,160              ;point source address to the next row down
  153.            Add  BX,160              ;ditto for the destination
  154.  
  155.            Dec  CH                  ;show that we just completed another row
  156.            Jnz  Next_Row            ;do the next row if there still is one to do
  157.  
  158.  
  159. Done:      Pop  DS
  160.            Pop  BP
  161.  
  162. RScroll    Endp
  163. Code       Ends
  164.            End   Begin
  165.